package definition;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import definition.comparable.OneselfClass;
import definition.comparable.SubClass;

/**
 * 泛型有序集合演示
 * @author fidel
 */
public class GenericListDemo {
    private List<OneselfClass> oneselfClassList = new ArrayList<>(10);
    
    @Before
    public void initialized() {
        for (int num = 0; num < 2; num++) {
            oneselfClassList.add(new OneselfClass());
            oneselfClassList.add(new SubClass());
        }
    }
    
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Test
    public void switchTest() {
        // 未指定泛型的有序集合可以存储任意类型的元素
        List list = new ArrayList<Integer>(10);
        list.add(Boolean.TRUE);
        list.add("element");
        list.add(-1);
        Iterator<Object> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        System.out.println("有序集合的大小为" + list.size());
        // 将未指定泛型的有序集合的引用指向已指定泛型的有序集合
        List<Object> objectList = list;
        objectList.add(false);
        objectList.add(new Serializable() {
            private static final long serialVersionUID = 1L;});
        System.out.println(objectList.get(objectList.size() - 1));
        /*
         * 未指定泛型的有序集合允许转换为任意泛型的有序集合
         * 已指定泛型的有序集合不能在其内部添加任何非当前泛型元素
         */
        List<Character> characterList = list;
        characterList.add('z');
        Iterator<Character> characterIterator = characterList.iterator();
        while (characterIterator.hasNext()) {
            System.out.println(characterIterator.next());
        }
        /*
         * 已指定泛型的有序集合允许转换为泛型是通用类型的有序集合
         * 通用泛型的有序集合不能在其内部添加任何非null元素
         */
        List<?> genericList = characterList;
        genericList.remove(2);
        genericList.set(1, null);
        // 两个已指定泛型的有序集合无法相互转换，除非一方的泛型是通用类型
        List<Boolean> booleanList = (List<Boolean>) genericList;
        booleanList.add(false);
    }
    
    /**
     * 实现指定类的通用泛型<? extends T>的有序集合不能在其内部放入元素
     * 取出的元素的泛型变为T
     */
    @Test
    public void extendsGenericListTest() {
        List<? extends OneselfClass> extendsTypeList = oneselfClassList;
        System.out.println("extendsType有序集合的大小为" + extendsTypeList.size());
        System.out.println("遍历extendsTypeList");
        for (int index = 0; index < extendsTypeList.size(); index++) {
            // 从List<? extends OneselfClass>中取出的元素依旧存在泛型
            OneselfClass oneself = extendsTypeList.get(index);
            System.out.println(oneself);
        }
    }
    
    /**
     * 指定类的通用超类泛型<? super T>的有序集合从其内部取出的元素的泛型丢失
     */
    @Test
    public void superGenericListTest() {
        List<? super OneselfClass> superTypeList = oneselfClassList;
        for (int num = 0; num < 2; num++) {
            superTypeList.add(new OneselfClass());
            superTypeList.add(new SubClass());
        }
        System.out.println("superType有序集合的大小为" + superTypeList.size());
        System.out.println("遍历superTypeList");
        for (int index = 0; index < superTypeList.size(); index++) {
            // 从List<? super OneselfClass>中取出的元素丢失泛型
            Object object = superTypeList.get(index);
            System.out.println(object);
        }
    }
}
